package com.example.bgmachine.bgmachine.modbus;


import java.util.ArrayList;
import java.util.List;

public class ModbusUtils {

    /**
     * 读指令
     * @param deviceAddress 设备地址
     * @param registerAddress 寄存器起始地址
     * @param registerCount 寄存器个数
     * @return
     */
    public static byte[] getReadModbus(int deviceAddress, int registerAddress, int registerCount) {
        int registerLow = registerAddress & 0xFF;
        int registerHigh = registerAddress >>> 8;
        int countLow = registerCount & 0xFF;
        int countHigh = registerCount >>> 8;
        int[] data = new int[]{registerHigh, registerLow, countHigh, countLow};
        byte[] sendData = getModbusData(deviceAddress, 0x03, data);
        return sendData;
    }

    /**
     * 写指令
     * @param deviceAddress 设备地址
     * @param registerAddress 寄存器起始地址
     * @param writeData 寄存器个数
     * @return
     */
    public static byte[] getWriteModbus(int deviceAddress, int registerAddress, int[] writeData) {
        int registerLow = registerAddress & 0xFF;
        int registerHigh = registerAddress >>> 8;
        int[] data = new int[writeData.length + 2];
        data[0] = registerHigh;
        data[1] = registerLow;
        for (int i = 0; i < writeData.length; i ++) {
            data[i + 2] = writeData[i];
        }
        byte[] sendData = getModbusData(deviceAddress, 0x06, data);
        return sendData;
    }

    public static List<Byte> isValidModbusResponseData(List<Byte> list) {
        if (null != list && list.size() >= 4) {
            int size = list.size();
            int leng = ByteUtils.byteToInt(list.get(2));
            int totalSize = leng + 5;
            if (size < totalSize) {
                return null;
            }
            List tempList = list.subList(0, totalSize - 2);
            byte[] tempData = ArrayUtils.listTobyte(tempList);
            int crc = CRCUtils.getCRC(tempData);
            int low = crc & 0xFF;
            int high = crc >>> 8;
            byte lowData = list.get(totalSize - 2);
            byte hightData = list.get(totalSize - 1);
            if (low == ByteUtils.byteToInt(lowData) && high == ByteUtils.byteToInt(hightData)) {
                return list.subList(0, totalSize);
            } else {
                return null;
            }
        } else {
            return null;
        }
    }

    public static byte[] getModbusData(int address, int function, int[] data) {
        int leng = 2;
        if (null != data) {
            leng += data.length;
        }
        byte[] tempData = new byte[leng];
        tempData[0] = ByteUtils.intToByte(address);
        tempData[1] = ByteUtils.intToByte(function);
        if (null != data) {
            for (int i = 0; i < data.length; i++) {
                tempData[i + 2] = ByteUtils.intToByte(data[i]);
            }
        }
        int crc = CRCUtils.getCRC(tempData);
        int low = crc & 0xFF;
        int high = crc >>> 8;
        List list = new ArrayList();
        list.addAll(ArrayUtils.byteToList(tempData));
        list.add(ByteUtils.intToByte(low));
        list.add(ByteUtils.intToByte(high));
        return ArrayUtils.listTobyte(list);
    }
}
